package com.j1ay.forum.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.j1ay.forum.dao.mapper.CheckMapper;
import com.j1ay.forum.dao.mapper.QuestionMapper;
import com.j1ay.forum.model.dto.params.CheckStatusParams;
import com.j1ay.forum.model.dto.params.PageParams;
import com.j1ay.forum.model.dto.params.UpdateUserParams;
import com.j1ay.forum.model.pojo.JwtUser;
import com.j1ay.forum.model.pojo.po.Check;
import com.j1ay.forum.model.pojo.po.Question;
import com.j1ay.forum.model.pojo.vo.*;
import com.j1ay.forum.service.CheckService;
import com.j1ay.forum.service.QuestionService;
import com.j1ay.forum.service.TypeService;
import com.j1ay.forum.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import javax.security.auth.callback.CallbackHandler;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Author J1ay
 * @Date 2021/12/21 18:09
 * @Description
 */
@Service
public class CheckServiceImpl implements CheckService {

    @Autowired(required = false)
    private QuestionMapper questionMapper;

    @Autowired(required = false)
    private CheckMapper checkMapper;

    @Autowired
    private UserService userService;
    @Autowired
    private TypeService typeService;
    @Autowired
    private QuestionService questionService;

    // 类型转换
    private List<QuestionVo> copyList(List<Question> records,boolean isType,boolean isAuthor) {
        List<QuestionVo> questionVoList = new ArrayList<>();
        for (Question record: records) {
            questionVoList.add(copy(record, isType, isAuthor));
        }
        return questionVoList;
    }

    private QuestionVo copy(Question question,boolean isType,boolean isAuthor) {
        QuestionVo questionVo = new QuestionVo();
        BeanUtils.copyProperties(question, questionVo);
        questionVo.setCreateTime(new DateTime(question.getCreateTime()).toString("yyyy-MM-dd HH:mm"));
        questionVo.setUpdateTime(new DateTime(question.getUpdateTime()).toString("yyyy-MM-dd HH:mm"));
        if(isType){
            Long typeId = question.getTypeId();
            System.out.println(typeId);
            questionVo.setType(typeService.findTypeByTypeId(typeId));
        }
        if (isAuthor) {
            //拿到作者id
            String username = question.getUsername();
            System.out.println(username);
            questionVo.setAuthorName(userService.findUserById(username).getNickname());
        }
        return questionVo;
    }

    /**
     * 获取所有的问题列表
     * @param pageParams
     * @return
     */
    @Override
    public Result listAllQuestion(PageParams pageParams) {
        Page<Question> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        // 先按置顶排序，再按创建的时间倒序排序
        if (StringUtils.isNotBlank(pageParams.getQueryString())) {
            queryWrapper.and(c -> c.like(Question::getTitle, pageParams.getQueryString())
                    .or().like(Question::getUsername, pageParams.getQueryString())
                    .or().like(Question::getContent, pageParams.getQueryString()));
        }
        queryWrapper.orderByDesc(Question::getZhiding, Question::getCreateTime);
        Page<Question> questionPage = questionMapper.selectPage(page, queryWrapper);
        List<Question> records = questionPage.getRecords();
        List<QuestionVo> questionVoList = copyList(records, true, true);

        PageResult<QuestionVo> result = new PageResult();
        result.setCurrentPage(questionPage.getCurrent());
        result.setPageSize(questionPage.getSize());
        result.setList(questionVoList);
        result.setTotals(questionPage.getTotal());

        return Result.success(result);
    }


    /**
     * 根据问题审核状态获取问题列表
     * @param checkStatusParams
     * @return
     */
    @Override
    public Result listQuestionByStatus(CheckStatusParams checkStatusParams) {
        PageParams pageParams = checkStatusParams.getPageParams();
        int nowStatus = checkStatusParams.getStatus();

        if (Objects.isNull(pageParams) || Objects.isNull(nowStatus)) {
            return Result.fail(ErrorCode.PARAMS_BLANK.getCode(), ErrorCode.PARAMS_BLANK.getMsg());
        }

        Page<Question> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        LambdaQueryWrapper<Question> queryWrapper = new LambdaQueryWrapper<>();
        // 先筛选审核，按置顶排序，再按创建的时间倒序排序
        queryWrapper.eq(Question::getStatus, nowStatus);
        if (StringUtils.isNotBlank(pageParams.getQueryString())) {
            queryWrapper.and(c -> c.like(Question::getTitle, pageParams.getQueryString())
                    .or().like(Question::getUsername, pageParams.getQueryString())
                    .or().like(Question::getContent, pageParams.getQueryString()));
        }
        queryWrapper.orderByDesc(Question::getZhiding, Question::getCreateTime);
        Page<Question> questionPage = questionMapper.selectPage(page, queryWrapper);
        List<Question> records = questionPage.getRecords();
        List<QuestionVo> questionVoList = copyList(records, true, true);

        PageResult<QuestionVo> result = new PageResult();
        result.setCurrentPage(questionPage.getCurrent());
        result.setPageSize(questionPage.getSize());
        result.setList(questionVoList);
        result.setTotals(questionPage.getTotal());

        return Result.success(result);
    }


    @Override
    public Result getCheckListByUserId(PageParams pageParams) {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long userId = ((JwtUser)principal).getId();
        if (Objects.isNull(userId)) {
            return Result.fail(ErrorCode.TOKEN_FAILED.getCode(), ErrorCode.TOKEN_FAILED.getMsg());
        }
        Page<Check> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        LambdaQueryWrapper<Check> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Check::getUserId, userId);
        queryWrapper.orderByDesc(Check::getResult,Check::getProcessTime);
        Page<Check> checkPage = checkMapper.selectPage(page, queryWrapper);
        List<Check> checkList = checkPage.getRecords();
        System.out.println("====principal===" + ((JwtUser)principal).getId());

        List<CheckVo> checkVos = toCheckVoList(checkList);

        PageResult<CheckVo> result = new PageResult();
        result.setCurrentPage(checkPage.getCurrent());
        result.setPageSize(checkPage.getSize());
        result.setList(checkVos);
        result.setTotals(checkPage.getTotal());
        return Result.success(result);
    }

    /**
     * check ===> checkVo
     * @param checkList
     * @return
     */
    private List<CheckVo> toCheckVoList(List<Check> checkList) {
        List<CheckVo> checkVoList = new ArrayList<>();
        for (Check check : checkList) {
            checkVoList.add(toCheckVo(check));
        }
        return checkVoList;
    }

    /**
     * check --- checkVo
     * @param check
     * @return
     */
    private CheckVo toCheckVo(Check check) {
        CheckVo checkVo = new CheckVo();
        BeanUtils.copyProperties(check, checkVo);
        QuestionVo questionVo = questionService.findQuestionVoById(check.getQuestionId());
        LoginUserVo loginUserVo = userService.findUserByUserId(check.getUserId());
        checkVo.setLoginUserVo(loginUserVo);
        checkVo.setProcessTime(new DateTime(check.getProcessTime()).toString("yyyy-MM-dd HH:mm"));
        checkVo.setQuestionVo(questionVo);
        return checkVo;
    }

    @Override
    public Result getCheckList(PageParams pageParams) {
        Page<Check> page = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        LambdaQueryWrapper<Check> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Check::getResult,Check::getProcessTime);
        Page<Check> checkPage = checkMapper.selectPage(page, queryWrapper);
        List<Check> checkList = checkPage.getRecords();
        List<CheckVo> checkVos = toCheckVoList(checkList);

        PageResult<CheckVo> result = new PageResult();
        result.setCurrentPage(checkPage.getCurrent());
        result.setPageSize(checkPage.getSize());
        result.setList(checkVos);
        result.setTotals(checkPage.getTotal());
        return Result.success(result);
    }

    @Override
    public Result toCheck(Check check) {
        Long questionId = check.getQuestionId();
        int status = check.getResult();
        if (Objects.isNull(questionId) || Objects.isNull(status)) {
            return Result.fail(ErrorCode.PARAMS_BLANK.getCode(), ErrorCode.PARAMS_BLANK.getMsg());
        }
        Question question = questionMapper.selectById(questionId);
        if (question.getStatus() == status && status != 0) {
            return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), "无法执行该审核操作，请重新选择~");
        }
        check.setProcessTime(new Date());
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Long userId = ((JwtUser)principal).getId();
        check.setUserId(userId);
        int ress = checkMapper.insert(check);
        if (0 == ress) {
            return Result.fail(ErrorCode.SESSION_FAILED.getCode(), ErrorCode.SESSION_FAILED.getMsg());
        }
        question.setStatus(status);
        int res = questionMapper.updateById(question);
        if (0 == res) {
            return Result.fail(ErrorCode.SESSION_FAILED.getCode(), ErrorCode.SESSION_FAILED.getMsg());
        }
        return Result.success(null);
    }
}
